package dao;

import model.Goods;
import model.GoodsSale;
import util.*;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.Month;
import java.util.List;

public class GoodsSalesManager implements GoodsSalesManagement {

    /**
     * 新建一项打折活动
     * @param sale 打折活动信息对象
     * @return 打折活动信息id
     */
    @Override
    public Long newSaleAction(GoodsSale sale) {

        if(sale == null  ||  sale.getG_id() == null  ||
                sale.getG_bonus() == null && sale.getG_sale() == null && sale.getG_vip_sale() == null ||
                sale.getG_sale_close() == null
        ) return null;

        StringBuilder sql_cols = new StringBuilder("g_sale_id, g_id");
        StringBuilder sql_args = new StringBuilder("null, ?");

        ArgsList<Object> args  = new ArgsList<>();

        args.add(sale.getG_id());

        if(sale.getG_sale() != null) {
            if(sale.getG_sale() > 100 || sale.getG_sale() < 0) sale.setG_sale(100);
            sql_cols.append(", g_sale");
            sql_args.append(", ?");
            args.add(sale.getG_sale());
        }
        if(sale.getG_vip_sale() != null) {
            if(sale.getG_vip_sale() > 100 || sale.getG_vip_sale() < 0) sale.setG_vip_sale(100);
            sql_cols.append(", g_vip_sale");
            sql_args.append(", ?");
            args.add(sale.getG_vip_sale());
        }
        if(sale.getG_bonus() != null) {
            if(sale.getG_bonus() > 100 || sale.getG_bonus() < 0) sale.setG_bonus(100);
            sql_cols.append(", g_bonus");
            sql_args.append(", ?");
            args.add(sale.getG_bonus());
        }

        sql_cols.append(", g_sale_open");

        if(sale.getG_sale_open() != null) {
            sql_args.append(", ?");
            args.add(sale.getG_sale_open());
        } else {
            sql_args.append(", CURRENT_TIMESTAMP");
        }

        sql_cols.append(", g_sale_close");
        sql_args.append(", ?");
        args.add(sale.getG_sale_close());

        if(!Common.isStringEmpty(sale.getG_sale_descript())) {
            sql_cols.append(", g_sale_descript");
            sql_args.append(", ?");
            args.add(sale.getG_sale_descript());
        }

        try {
            JDBCConnection conn = JDBCFactory.takeJDBC();
            Long gKey = ((BigInteger) conn.updateForGeneratedKey(args, "insert into t_gsale(" + sql_cols + ") values(" + sql_args + ")")).longValue();
            JDBCFactory.returnBack(conn);

            return gKey;
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据商品类别新建一项打折活动
     * @param sale 打折活动信息对象
     * @param goodsTypID 打折活动商品类型id
     * @return 参与打折的商品种类数量
     */
    @Override
    public int newSaleAction(GoodsSale sale, Long goodsTypID) {

        if(sale == null  ||
                sale.getG_bonus() == null && sale.getG_sale() == null && sale.getG_vip_sale() == null ||
                sale.getG_sale_close() == null
        ) return 0;

        StringBuilder sql_cols = new StringBuilder("g_sale_id");
        StringBuilder sql_args = new StringBuilder("null");

        ArgsList<Object> args  = new ArgsList<>();

        if(sale.getG_sale() != null) {
            if(sale.getG_sale() > 100 || sale.getG_sale() < 0) sale.setG_sale(100);
            sql_cols.append(", g_sale");
            sql_args.append(", ?");
            args.add(sale.getG_sale());
        }
        if(sale.getG_vip_sale() != null) {
            if(sale.getG_vip_sale() > 100 || sale.getG_vip_sale() < 0) sale.setG_vip_sale(100);
            sql_cols.append(", g_vip_sale");
            sql_args.append(", ?");
            args.add(sale.getG_vip_sale());
        }
        if(sale.getG_bonus() != null) {
            if(sale.getG_bonus() > 100 || sale.getG_bonus() < 0) sale.setG_bonus(100);
            sql_cols.append(", g_bonus");
            sql_args.append(", ?");
            args.add(sale.getG_bonus());
        }

        sql_cols.append(", g_sale_open");

        if(sale.getG_sale_open() != null) {
            sql_args.append(", ?");
            args.add(sale.getG_sale_open());
        } else {
            sql_args.append(", CURRENT_TIMESTAMP");
        }

        sql_cols.append(", g_sale_close");
        sql_args.append(", ?");
        args.add(sale.getG_sale_close());

        if(!Common.isStringEmpty(sale.getG_sale_descript())) {
            sql_cols.append(", g_sale_descript");
            sql_args.append(", ?");
            args.add(sale.getG_sale_descript());
        }

        sql_cols.append(", g_id");
        sql_args.append(", ?");

        long count = 0;

        try {
            JDBCConnection conn = JDBCFactory.takeJDBC();
            conn.start();

            //查找指定商品类型下的所有商品id
            List<Object[]> g_ids = conn.query("select g_id from t_goodsoftype where gtyp_id = ?", goodsTypID);

            conn.preparedUpdateBatch("insert into t_gsale(" + sql_cols + ") values(" + sql_args + ")");

            for (Object[] g_idRow : g_ids) {
                args.add(g_idRow[0]);
                conn.addUpdateBatchWithArgsList(args);
                args.removeLast();
            }
            conn.submitUpdateBatch();
            conn.commit();
            JDBCFactory.returnBack(conn);

            return g_ids.size();
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return 0;
        }
    }
    /**
     * 终止一项打折活动
     * @param saleID 打折活动id
     * @return 成功返回true，失败返回false
     */
    @Override
    public boolean terminate(long saleID) {
        try {
            JDBCConnection conn = JDBCFactory.takeJDBC();
            int count = conn.update("update t_gsale set g_sale_close = CURRENT_TIMESTAMP where g_sale_id = ?", saleID);
            JDBCFactory.returnBack(conn);
            return count == 1;
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return false;
        }
    }

    /**
     * 终止一个商品上正在进行的全部打折活动
     * @param goods 商品
     * @return 受影响的活动数
     */
    @Override
    public int terminate(Goods goods) {
        try {
            JDBCConnection conn = JDBCFactory.takeJDBC();
            int count = conn.update("update t_gsale set g_sale_close = CURRENT_TIMESTAMP where g_id = ?", goods.getG_id());
            JDBCFactory.returnBack(conn);
            return count;
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return 0;
        }
    }

    /**
     * 查询一个商品上正在进行的全部打折活动信息
     * @param goodsID 商品id
     * @return 全部的打折信息列表
     */
    @Override
    public List<GoodsSale> query(Long goodsID) {
        try {
            JDBCConnection conn = JDBCFactory.takeJDBC();
            List<Object[]> list = conn.query("select * from t_gsale where g_id = ? and CURRENT_TIMESTAMP between g_sale_open and g_sale_close", goodsID);
            JDBCFactory.returnBack(conn);
            if (list.isEmpty()) return null;
            return getResultList(list);
        } catch(SQLException e) {
            System.err.println(e.getMessage());
            return null;
        }
    }

    /**
     * 合并叠加一个商品上的全部折扣信息
     * @param saleList 同一个商品正在进行的打折活动信息列表
     * @return 包含合并后折扣的打折信息对象
     */
    public static GoodsSale merge(List<GoodsSale> saleList) {
        if(saleList == null) return null;
        GoodsSale result = new GoodsSale();
        result.setG_sale(100);
        result.setG_vip_sale(100);
        result.setG_bonus(100);

        Integer tmp = null;
        for(GoodsSale each : saleList) {
            if((tmp = each.getG_sale()) != null) result.setG_sale(result.getG_sale() * tmp / 100);
            if((tmp = each.getG_vip_sale()) != null) result.setG_vip_sale(result.getG_vip_sale() * tmp / 100);
            if((tmp = each.getG_bonus()) != null) result.setG_bonus(result.getG_bonus() * tmp / 100);
        }

        return result;
    }

    /**
     * 根据叠加后的折扣信息计算当前每件商品的折后价
     * @param goods 要打折的商品
     * @param sale  包含合并后折扣的打折信息对象
     * @return      商品的折后价
     */
    public static BigDecimal getSalePrice(Goods goods, GoodsSale sale) {
        if(goods == null  ||  sale == null  ||  sale.getG_sale() == null  ||  sale.getG_sale() > 100  ||  sale.getG_sale() < 0) return null;

        BigDecimal price = null;
        price = goods.getG_price().multiply(new BigDecimal(sale.getG_sale().toString())).divide(new BigDecimal("100"));;
        return price;
    }

    /**
     * 根据叠加后的折扣信息计算当前每件商品的折后会员价
     * @param goods 要打折的商品
     * @param sale  包含合并后折扣的打折信息对象
     * @return      商品的折后会员价
     */
    public static BigDecimal getVIPSalePrice(Goods goods, GoodsSale sale) {
        if(goods == null  ||  sale == null  ||  sale.getG_vip_sale() == null  ||  sale.getG_vip_sale() > 100  ||  sale.getG_vip_sale() < 0) return null;

        BigDecimal price = null;
        price = goods.getG_vip_price().multiply(new BigDecimal(sale.getG_vip_sale().toString())).divide(new BigDecimal("100"));;
        return price;
    }

    /**
     * 根据叠加后的折扣信息计算当前每件商品的平台红利金
     * @param goods 活动中的商品
     * @param sale  包含合并后折扣的打折信息对象
     * @return      商品的平台红利金
     */
    public static BigDecimal getBonus(Goods goods, GoodsSale sale) {
        if(goods == null  ||  sale == null  ||  sale.getG_bonus() == null  ||  sale.getG_bonus() > 100  ||  sale.getG_bonus() < 0) return null;

        BigDecimal price = null;
        price = goods.getG_price().multiply(new BigDecimal(sale.getG_bonus().toString())).divide(new BigDecimal("100"));
        return price;
    }

    /**
     * 包装并返回查询到的对象的列表
     * @param list 包含 SQL 行查询结果的列表，Object[]中每一项都是一列的值
     * @return 返回包装好的对象列表
     */
    private static List<GoodsSale> getResultList(List<Object[]> list)
    {
        List<GoodsSale> result = new ResultList<>();
        for(Object[] row : list) result.add(new GoodsSale(row));
        return result;
    }

    public static void main(String[] args) {
        GoodsSalesManager gsm = new GoodsSalesManager();

        GoodsSale gs = new GoodsSale();
        Goods tmp = new Goods();
        tmp.setG_id(3);
        Goods g = new GoodsManager().query(tmp).get(0);

        gsm.terminate(g);

        System.out.println(g);

        gs.setG_id(3L);
        gs.setG_sale(70);
        gs.setG_vip_sale(60);
        gs.setG_sale_close(LocalDateTime.of(2021, Month.SEPTEMBER, 10, 14, 46, 56));
        gs.setG_bonus(3);
        gs.setG_sale_descript("测试打折活动");

        //gsm.newSaleAction(gs);
        gsm.newSaleAction(gs, 1L);

        System.out.println(getSalePrice(g, merge(gsm.query(3L))));
    }
}
